package common;

import java.awt.image.BufferedImage;

import java.sql.Timestamp;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import java.util.ResourceBundle;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import javax.portlet.PortletRequest;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.component.UIComponent;

import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCIteratorBinding;

import oracle.adf.view.rich.component.rich.RichPopup;

import oracle.adf.view.rich.context.AdfFacesContext;

import oracle.binding.BindingContainer;
import oracle.binding.OperationBinding;

import oracle.jbo.ViewCriteria;
import oracle.jbo.ViewCriteriaItem;
import oracle.jbo.ViewCriteriaRow;
import oracle.jbo.ViewObject;
import oracle.jbo.uicli.binding.JUCtrlRangeBinding;

import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;

public class Utils {
    public Utils() {
        super();
    }

    public final static Severity MSG_FATAL = FacesMessage.SEVERITY_FATAL;
    public final static Severity MSG_ERROR = FacesMessage.SEVERITY_ERROR;
    public final static Severity MSG_WARN = FacesMessage.SEVERITY_WARN;
    public final static Severity MSG_INFO = FacesMessage.SEVERITY_INFO;

    public static void showMessage(Severity severity, String sMsg) {
        FacesMessage msg = new FacesMessage(severity, null, sMsg);
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, msg);
    }

    public static void showMessage(String clientId, Severity severity,
                                   String title, String sMsg) {
        FacesMessage msg = new FacesMessage(severity, title, sMsg);
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(clientId, msg);
    }
    
    public static void showPopup(RichPopup pId){
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExtendedRenderKitService service =
            Service.getRenderKitService(facesContext,
                                        ExtendedRenderKitService.class);
        service.addScript(facesContext,
                          "AdfPage.PAGE.findComponent('" + pId.getClientId(facesContext) +
                          "').show();");
    }

    public static PortletRequest getPortletRequest() {
        PortletRequest req =
            (PortletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
        return req;
    }
    
    public static boolean isPostBack(){
        if (Boolean.FALSE.equals(getElExpression("#{adfFacesContext.postback}")))
            return true;    
        else
            return false;
    }

    public static Locale getPortalLocale() {
        Locale portalLocale = new Locale("vi", "VN");
        String language = "";
        try {
            if (getPortletRequest().getParameter("ngonnguid") != null) {
                language = getPortletRequest().getParameter("ngonnguid");
                portalLocale = new Locale(language);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return portalLocale;
    }

    public static String getResource(String resourceKey) {
        Locale locale = getPortalLocale();
        ResourceBundle bundle =
            ResourceBundle.getBundle("model.PortletsBundle", locale);
        return bundle.getString(resourceKey);
    }
    
    /**
     * @param Id
     * @param iteratorName
     * @return
     */
    public static String getValueById(String keyValue, String iteratorName) {
        String vl = null;
        if (keyValue != null) {
            DCIteratorBinding iterator1 =
                Utils.getIteratorBinding(iteratorName);
            iterator1.setCurrentRowWithKeyValue(keyValue);
            vl = String.valueOf(iterator1.getCurrentRow().getAttribute("TenFile"));
        }
        return vl;
    }

    public static void search(String iteratorName,
                              Map<String, Object>... mapPredicates) {
        try {
            DCIteratorBinding iter = getIteratorBinding(iteratorName);
            ViewObject vo =
                iter.getRowSetIterator().getRowSet().getViewObject();
            ViewCriteria vc = vo.createViewCriteria();
            int count = mapPredicates.length;
            for (int i = 0; i < count; i++) {
                Map<String, Object> mapPredicate = mapPredicates[i];
            ViewCriteriaRow vcr = vc.createViewCriteriaRow();
            Iterator it = mapPredicate.keySet().iterator();
            while (it.hasNext()) {
                String key = (String)it.next();
                Object value = mapPredicate.get(key);
                if (value != null) {
                    if(value instanceof Date){
                        Date date = (Date)value;
                        Timestamp sqlTimestamp =
                            new java.sql.Timestamp(date.getTime());
                        value = new oracle.jbo.domain.Date(sqlTimestamp);
                    }
                    vcr.setAttribute(key, value);
             
                }
            }
            vc.add(vcr);
            }
            vc.setUpperColumns(true);
            vo.getViewCriteriaManager().clearViewCriterias();
            vo.getViewCriteriaManager().applyViewCriteria(vc);
            iter.executeQuery();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    /**
     * @param iteratorName
     * @param operator
     * @param field
     * @param comparevalue
     */
    public static void searchNgayhethan(String iteratorName,String operator,String field,String comparevalue
                             ) {
        try {
            DCIteratorBinding iter = getIteratorBinding(iteratorName);
            ViewObject vo =
                iter.getRowSetIterator().getRowSet().getViewObject();
            ViewCriteria vc = vo.createViewCriteria();
           
            ViewCriteriaRow vcr = vc.createViewCriteriaRow();
            ViewCriteriaItem jobItem = vcr.ensureCriteriaItem(field);
            jobItem.setOperator(operator);
            jobItem.getValues().get(0).setValue(comparevalue);
            vc.add(vcr);                       
            vo.getViewCriteriaManager().clearViewCriterias();
            vo.getViewCriteriaManager().applyViewCriteria(vc);
            iter.executeQuery();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
    
    /**
     * Refresh a View Iterator
     * @param iteratorName
     */
    public static void iteratorRefresh(String iteratorName) {
        try {
            DCBindingContainer dcBinding =
                (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
            DCIteratorBinding ViewIterator =
                (DCIteratorBinding)dcBinding.get(iteratorName);
            ViewIterator.getViewObject().clearCache();
            ViewIterator.executeQuery();
            ViewIterator.refresh(DCIteratorBinding.RANGESIZE_UNLIMITED);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static List execute(String operator) {
        try {
            BindingContainer bindings = getBindings();
            OperationBinding operationBinding =
                bindings.getOperationBinding(operator);
            Object result = operationBinding.execute();
            if (operationBinding.getErrors() != null &&
                operationBinding.getErrors().size() > 0) {
                return operationBinding.getErrors();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * @param el
     * @return
     */
    public static Object getElExpression(String el) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ELContext elContext = facesContext.getELContext();
        ExpressionFactory expressionFactory =
            facesContext.getApplication().getExpressionFactory();
        ValueExpression valueExp =
            expressionFactory.createValueExpression(elContext, el,
                                                    Object.class);
        return valueExp.getValue(elContext);
    }

    /**
     * @param el
     * @param val
     */
    public static void setElExpression(String el, Object val) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ELContext elContext = facesContext.getELContext();
        ExpressionFactory expressionFactory =
            facesContext.getApplication().getExpressionFactory();
        ValueExpression exp =
            expressionFactory.createValueExpression(elContext, el,
                                                    Object.class);
        exp.setValue(elContext, val);
    }
    

    /**
     * @return
     */
    public static FacesContext getFacesContext() {
        return FacesContext.getCurrentInstance();
    }

    /**
     * @param iteratorName
     * @return
     */
    public static DCIteratorBinding getIteratorBinding(String iteratorName) {
        DCIteratorBinding dc = getDCBindingContainer().findIteratorBinding(iteratorName);
        return dc;
    }

    /**
     * @return
     */
    public static DCBindingContainer getDCBindingContainer() {
        return (DCBindingContainer)getBindingContainer();
    }

    /**
     * @return
     */
    public static BindingContainer getBindingContainer() {
        return (BindingContainer)getElExpression("#{bindings}");
    }

    /**
     * @return
     */
    public static BindingContainer getBindings() {
        return BindingContext.getCurrent().getCurrentBindingsEntry();
    }
    
    public static oracle.jbo.domain.Date getCurrentDate() {
        Date now = new Date();
        Timestamp timestamp=new Timestamp(now.getTime());
        oracle.jbo.domain.Date jboDate=new oracle.jbo.domain.Date(timestamp);
        return jboDate;
    }
    
    public static String goLastPage(Integer RANGE_SIZE,
                                    String viewObjectName) {
        JUCtrlRangeBinding OV = getViewObject(viewObjectName);
        long lastPageNum =
            Math.max(1, (OV.getIteratorBinding().getEstimatedRowCount() - 1) /
                     RANGE_SIZE + 1);
        if (lastPageNum <= 1)
            return null;
        int prePage =
            OV.getIteratorBinding().getNavigatableRowIterator().getRangeStart() /
            RANGE_SIZE + 1;
        OV.getIteratorBinding().getNavigatableRowIterator().scrollRange((int)(RANGE_SIZE *
                                                                              (lastPageNum -
                                                                               prePage)));
        OV.setCurrentRowAtIndex(0);
        return null;
    }

    public static boolean isLastEnabled(Integer RANGE_SIZE,
                                        String viewObjectName) {
        JUCtrlRangeBinding OV = getViewObject(viewObjectName);
        long lastPageNum =
            Math.max(1, (OV.getIteratorBinding().getEstimatedRowCount() - 1) /
                     RANGE_SIZE + 1);
        long currentPage =
            OV.getIteratorBinding().getNavigatableRowIterator().getRangeStart() /
            RANGE_SIZE + 1;
        return currentPage < lastPageNum;
    }
    
    public static boolean isFirstEnabled(Integer RANGE_SIZE,
                                        String viewObjectName) {
        boolean isFirst = true;
        JUCtrlRangeBinding OV = getViewObject(viewObjectName);
        long currentPage =
            OV.getIteratorBinding().getNavigatableRowIterator().getRangeStart() /
            RANGE_SIZE + 1;
        if(currentPage == 1){isFirst=false;}
        return isFirst;
    }

    public static JUCtrlRangeBinding getViewObject(String viewObjectName) {
        BindingContext bindingCtx = BindingContext.getCurrent();
        BindingContainer bindings = bindingCtx.getCurrentBindingsEntry();
        return (JUCtrlRangeBinding)bindings.getControlBinding(viewObjectName);
    }
}
